use crate::physical_plan::window::{WindowElement, WindowIndex, SortByValue};
use crate::conf_init::{MapResult, MapErr};
use crate::data_frame::value::{RealConfValue};
use crate::physical_plan::window::accumulator::counter::AccumulatorCounter;
use crate::data_frame::single_data::SingleData;
use crate::physical_plan::PhysicalPlanExprArg;
use std::fmt::Debug;

pub mod counter;

#[async_trait]
pub trait PhysicalPlanExprAccumulator<D,S>: Send+Sync+Debug {
    async fn _add(&mut self, data_arg: &[S], data: D) ->Result<(),()>;
    async fn _sub(&mut self, data_arg: &[S], data: D) ->Result<(),()>;
    async fn _check(&mut self) ->Result<bool,()>;
    fn _clone_self(&self) ->Box<dyn PhysicalPlanExprAccumulator<D,S>>;
}

#[async_trait]
pub trait PhysicalPlanExprAccumulatorComb<D: Clone+Send>: Send+Sync{
    async fn add(&mut self, data: D)->Result<(),()>;
    async fn sub(&mut self, data: D)->Result<(),()>;
    async fn check(&mut self)->Result<bool,()>;
    //async fn add_and_check<'a,'b>(&'a mut self, mut data: D)->Result<bool,()>;
    fn clone_self(&self) ->Self;
}

impl <K> WindowElement<K,Self> for usize{
    type MapValue = usize;
    fn index(&self)->WindowIndex{
        WindowIndex::new((*self as u128) << 64)
    }
    fn just_index(&self)->bool{
        false
    }
    fn index_to_value(&self)->Self::MapValue{
        self.clone()
    }
    fn index_value_ref(&self)->&Self::MapValue{
        &self
    }
    fn index_value_mut(&mut self)->&mut Self::MapValue{
        self
    }
}

impl <K> SortByValue<K,Self> for usize{
    fn get_key_value_always(&self, _k: &K) ->Self{
        self.clone()
    }
}

pub fn accumulator_by_name(accumulator_name: &str, conf_arg: &[RealConfValue])
    ->MapResult<Box<dyn PhysicalPlanExprAccumulator<SingleData, Box<PhysicalPlanExprArg>>>>{

    match accumulator_name{
        "counter" => {
            return AccumulatorCounter::new(conf_arg);
        },
        _ => {
            return MapResult::Err(MapErr::new(format!("accumulator [{}] not support", accumulator_name)));
        },
    }
}

